package com.tongwandou.starter.redis.helper.helper;

import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @name: RedisHelper
 * @description: RedisHelper
 * @author: jiangcs
 */
public class RedisHelper {
    private final RedisTemplate<String, Object> redisTemplate;

    public RedisHelper(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 设值
     *
     * @param key   关键字
     * @param value 值
     * @return -1-参数非法；1-成功
     */
    public <T> int setValue(String key, T value) {
        if (key == null || value == null) {
            return -1;
        }

        redisTemplate.opsForValue().set(key, value);
        return 1;
    }

    /**
     * 设值
     *
     * @param key     关键字
     * @param value   值
     * @param seconds 过期时长（秒）
     * @return -1-参数非法；1-成功
     */
    public <T> int setValue(String key, T value, long seconds) {
        if (key == null || value == null) {
            return -1;
        }

        redisTemplate.opsForValue().set(key, value, seconds, TimeUnit.SECONDS);
        return 1;
    }

    /**
     * 设值
     *
     * @param key   关键字
     * @param value 值
     * @return null||false-参数非法或关键字已存在；true-成功
     */
    public <T> Boolean setValueNX(String key, T value) {
        if (key == null || value == null) {
            return false;
        }

        return redisTemplate.opsForValue().setIfAbsent(key, value);
    }

    /**
     * 设值
     *
     * @param key     关键字
     * @param value   值
     * @param seconds 过期时长（秒）
     * @return null||false-参数非法或关键字已存在；true-成功
     */
    public <T> Boolean setValueNX(String key, T value, long seconds) {
        if (key == null || value == null) {
            return false;
        }

        return redisTemplate.opsForValue().setIfAbsent(key, value, seconds, TimeUnit.SECONDS);
    }

    /**
     * 取值
     *
     * @param key 关键字
     * @return null||Object
     */
    public Object getValue(String key) {
        if (key == null) {
            return null;
        }

        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 设值
     *
     * @param key      关键字
     * @param valueMap Map值
     * @return -1-参数非法；1-成功
     */
    public int setHashValueMap(String key, Map<Object, Object> valueMap) {
        if (key == null || valueMap == null) {
            return -1;
        }

        redisTemplate.opsForHash().putAll(key, valueMap);
        return 1;
    }

    /**
     * 取值
     *
     * @param key 关键字
     * @return null||Map<Object, Object>
     */
    public Map<Object, Object> getHashValueMap(String key) {
        if (key == null) {
            return null;
        }

        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 设值
     *
     * @param key       关键字
     * @param hashKey   Map关键字
     * @param hashValue Map值
     * @return -1-参数非法；1-成功
     */
    public int setHashValue(String key, Object hashKey, Object hashValue) {
        if (key == null || hashKey == null || hashValue == null) {
            return -1;
        }

        redisTemplate.opsForHash().put(key, hashKey, hashValue);
        return 1;
    }

    /**
     * 取值
     *
     * @param key     关键字
     * @param hashKey Map关键字
     * @return null||Object
     */
    public Object getHashValue(String key, Object hashKey) {
        if (key == null || hashKey == null) {
            return null;
        }

        return redisTemplate.opsForHash().get(key, hashKey);
    }

    /**
     * 删除
     *
     * @param key 关键字
     * @return null||false-失败；true-成功
     */
    public Boolean delete(String key) {
        return redisTemplate.delete(key);
    }

    /**
     * 设置过期时长
     *
     * @param key     关键字
     * @param seconds 过期时长（秒）
     * @return null||false-失败；true-成功
     */
    public Boolean expire(String key, long seconds) {
        return redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
    }

    /**
     * 选择数据库
     *
     * @param index 数据库索引，起始为0
     * @return -1-失败；0-未执行操作；1-成功
     */
    public int selectDB(int index) {
        if (index < 0) {
            return -1;
        }

        LettuceConnectionFactory lettuceConnectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
        if (lettuceConnectionFactory == null) {
            return -1;
        }
        if (index == lettuceConnectionFactory.getDatabase()) {
            return 0;
        }

        // 设置数据库索引
        lettuceConnectionFactory.setDatabase(index);

        // 重置链接工厂
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        lettuceConnectionFactory.resetConnection();

        // 刷新链接
        lettuceConnectionFactory.afterPropertiesSet();
        return 1;
    }
}
